package com.dsteiner.xelavos.server;

import static com.google.appengine.api.labs.taskqueue.TaskOptions.Builder.url;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.dsteiner.widgets.client.domain.ModelObject;
import com.dsteiner.widgets.client.domain.Sort;
import com.dsteiner.widgets.client.rpc.SearchRequest;
import com.dsteiner.widgets.client.rpc.SearchResult;
import com.dsteiner.widgets.server.dao.Parameter;
import com.dsteiner.widgets.server.dao.jdo.PMF;
import com.dsteiner.xelavos.client.domain.SavedSearch;
import com.dsteiner.xelavos.client.domain.SearchRequestXelavos;
import com.dsteiner.xelavos.client.domain.User;
import com.dsteiner.xelavos.server.EmailUtil.EmailUtilImpl;
import com.dsteiner.xelavos.server.dao.DataDao;
import com.google.appengine.api.labs.taskqueue.Queue;
import com.google.appengine.api.labs.taskqueue.QueueFactory;

public class SavedSearchesServlet extends HttpServlet {
	
	private static final Logger log = Logger.getLogger(SavedSearchesServlet.class.getName());
	private DataDao dataDao = DataDao.dataDao;
	private Queue queue = QueueFactory.getQueue("mail-queue");
	public static String noResultsMsg = "su busqueda no tuvo resultados";

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			checkSavedSearchReporting(req);
			
		} catch (Exception ex) {
			throw new ServletException(ex);
		}
	}

	private void checkSavedSearchReporting(HttpServletRequest req) {
		List<SavedSearch> savedSearches = getActiveSavedSearches();
		
		sendSavedSearches(savedSearches);
	}

	protected void sendSavedSearches(List<SavedSearch> savedSearches) {
		for (int i = 0; i < savedSearches.size(); i++) {
			SavedSearch savedSearch = savedSearches.get(i);
			SearchRequest searchRequest = new SearchRequestXelavos();
			searchRequest.setClassName(savedSearch.getSearchClassName());
			searchRequest.setSort(new Sort(savedSearch.getSearchSort()));
			searchRequest.setText(savedSearch.getSearchText());
			Date lastSentDate = savedSearch.getLastSentDate();
			searchRequest.setSort(new Sort("registeredDate", false));
			SearchResult<ModelObject> search = dataDao.search(searchRequest);
			List<ModelObject> objects = search.getObjects();
			StringBuffer plainTextSb = new StringBuffer();
			StringBuffer htmlTextSb = new StringBuffer();
			
			savedSearch.setLastSentDate(new Date());
			dataDao.updateObject(savedSearch);

			List<ModelObject> newObjects = new ArrayList<ModelObject>();
			if(objects != null){
				for (ModelObject object : objects) {
					if(object.getRegisteredDate().after(lastSentDate))
						newObjects.add(object);
				}
			}
			
			if(newObjects.isEmpty()){
				if(!savedSearch.isEmailIfNoMatches())
					continue;
				else{
					plainTextSb.append(noResultsMsg);
					htmlTextSb.append(noResultsMsg);
				}
			}

			for (ModelObject modelObject : newObjects) {
				EmailFormatter.format(modelObject, plainTextSb, htmlTextSb);
			}
			
			String deleteSavedSearchUrl = "http://www.xelavos.com/xelavos/emailAdmin?remove="
				+savedSearch.getClass().getName()+"&id="+savedSearch.getId();
			plainTextSb.append("\npara ya no recibir correos de esa busqueda visite el siguiente link\n").append(deleteSavedSearchUrl);
			htmlTextSb.append("<br>para ya no recibir correos de esa busqueda <a href=\""+deleteSavedSearchUrl+"\">haga click en ese link</a>");
			
			String htmlTextId = UUID.randomUUID().toString();
			String plainTextId = UUID.randomUUID().toString();
			EmailServlet.htmlTextMap.put(htmlTextId, htmlTextSb.toString());
			EmailServlet.plainTextMap.put(plainTextId, plainTextSb.toString());
			
			queue.add(url("/tasks/email")
					.param("userId", savedSearch.getUserId())
					.param("subject", "Los resultados de su busqueda "+savedSearch.getName())
					.param("htmlTextId", htmlTextId)
					.param("plainTextId", plainTextId));
		}
	}

	private List<SavedSearch> getActiveSavedSearches() {
		List<SavedSearch> savedSearches = new ArrayList<SavedSearch>();
		
		Calendar oneDayBeforeCalendar = Calendar.getInstance();
		oneDayBeforeCalendar.add(Calendar.DAY_OF_MONTH, +1);
		List dailyParametersList = new ArrayList<Parameter>();
		Parameter lastSendDateParameter = new Parameter("lastSentDateParam", oneDayBeforeCalendar.getTime());
		lastSendDateParameter.setComparator("<=");
		lastSendDateParameter.setType("java.util.Date");
		dailyParametersList.add(lastSendDateParameter);
		dailyParametersList.add(new Parameter("frequencyParam", SavedSearch.FREQUENCY_DAILY));
		List<SavedSearch> savedSearchesDaily = dataDao.getObjects(SavedSearch.class, dailyParametersList);
		savedSearches.addAll(savedSearchesDaily);
		
		Calendar oneWeekBeforeCalendar = Calendar.getInstance();
		oneDayBeforeCalendar.add(Calendar.DAY_OF_MONTH, -7);
		List weeklyParametersList = new ArrayList<Parameter>();
		lastSendDateParameter = new Parameter("lastSentDateParam", oneWeekBeforeCalendar.getTime());
		lastSendDateParameter.setComparator("<=");
		lastSendDateParameter.setType("java.util.Date");
		weeklyParametersList.add(lastSendDateParameter);
		weeklyParametersList.add(new Parameter("frequencyParam", SavedSearch.FREQUENCY_WEEKLY));
		List<SavedSearch> savedSearchesWeekly = dataDao.getObjects(SavedSearch.class, weeklyParametersList);
		savedSearches.addAll(savedSearchesWeekly);
		
		return savedSearches;
	}


	public void setQueue(Queue queue) {
		this.queue = queue;
	}
	
	public void setDataDao(DataDao dataDao) {
		this.dataDao = dataDao;
	}
	
	public void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		System.out.println("ImageServlet.doPost()");
	}
}